#include "CondimentDecorator.hpp"
#include "Coffee.hpp"

/*
  现有咖啡种类：黑咖啡(12)，黑暗烘烤黑咖啡(10)，浓缩咖啡(15)，低卡咖啡(20)
  调料：牛奶(5)，豆浆(3)，巧克力(10)，抹茶(8)，鲜奶油(12)
*/

// 案例一：一杯黑咖啡加上一份牛奶、一份豆浆(20)
void Test1()
{
  Beverage *houseBlend1 = new HouseBlend(); // 黑咖啡

  // 不匹配
  // Milk* milk1((Beverage*)houseBlend1);
  // Soy* soy1((Beverage*)milk1);

  Beverage *milk1 = new Milk(houseBlend1);
  Beverage *soy1 = new Soy(milk1);

  // CondimentDecorator tmp1; // 抽象类不能实例化对象
  // Milk* tmp; // 抽象类可以有对应的指针, 因为该指针并没有初始化。

  double fee1 = soy1->Cost();
  std::cout << "                           一号订单                           " << std::endl;
  std::cout << "一杯黑咖啡加上一份牛奶、一份豆浆" << std::endl;
  std::cout << "总计费用：" << fee1 << std::endl;
  std::cout << soy1->GetDescription() << std::endl;

  delete houseBlend1;
  delete milk1;
  delete soy1;
  std::cout << "#################################################################" << std::endl;
}

// 案例二：一杯黑暗烘烤咖啡加上两份鲜奶油(34)
void Test2()
{
  Beverage *darkRoast1 = new DarkRoast(); // 黑暗烘烤咖啡
  Beverage *Whip1 = new Whip(darkRoast1);
  Beverage *Whip2 = new Whip(Whip1);

  double fee1 = Whip2->Cost();
  std::cout << "                           二号订单                           " << std::endl;
  std::cout << "一杯黑暗烘烤咖啡加上两份鲜奶油" << std::endl;
  std::cout << "总计费用：" << fee1 << std::endl;
  std::cout << Whip2->GetDescription() << std::endl;

  delete darkRoast1;
  delete Whip1;
  delete Whip2;
  std::cout << "#################################################################" << std::endl;
}

// 案例三：两杯浓缩咖啡一杯加上一份抹茶和一份巧克力，另一杯加上两份鲜奶油(72)
void Test3()
{
  Beverage *espresson1 = new Espresson(); // 浓缩咖啡
  Beverage *mocha1 = new Mocha(espresson1);
  Beverage *chocolate1 = new Chocolate(mocha1);

  Beverage *espresson2 = new Espresson();
  Beverage *whip1 = new Whip(espresson2);
  Beverage *whip2 = new Whip(whip1);

  double fee1 = chocolate1->Cost();
  double fee2 = whip2->Cost();

  std::cout << "                           三号订单                           " << std::endl;
  std::cout << "两杯浓缩咖啡一杯加上一份抹茶和一份巧克力，另一杯加上两份鲜奶油" << std::endl;
  std::cout << "总计费用：" << fee1 + fee2 << std::endl;
  std::cout << chocolate1->GetDescription() << std::endl;
  std::cout << whip2->GetDescription() << std::endl;

  delete espresson1, espresson2;
  delete mocha1;
  delete chocolate1;
  delete whip1;
  delete whip2;
  std::cout << "#################################################################" << std::endl;
}

// 一杯低卡咖啡(20)
void Test4()
{
  Beverage *decaf1 = new Decaf(); // 低卡咖啡

  double fee1 = decaf1->Cost();
  std::cout << "                           四号订单                           " << std::endl;
  std::cout << "一杯低卡咖啡" << std::endl;
  std::cout << "总计费用：" << fee1 << std::endl;
  std::cout << decaf1->GetDescription() << std::endl;
  delete decaf1;
  std::cout << "#################################################################" << std::endl;
}

int main()
{
  Test1();
  Test2();
  Test3();
  Test4();
  return 0;
}
